using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System;

namespace SolutionOrchestrator
{
	public class CommandLineSourceControl : ObservableObject, ISourceControl, IDataErrorInfo
	{
		string _checkoutExecutable = @"%VS100ComnTools%..\IDE\TF.exe";

		public string CheckoutExecutable
		{
			get { return _checkoutExecutable; }
			set
			{
				_checkoutExecutable = value;
				OnPropertyChanged("CheckoutExecutable");
			}
		}

		string _checkoutArgumants = @"checkout ""{0}""";
		public string CheckoutArgumants
		{
			get { return _checkoutArgumants; }
			set
			{
				_checkoutArgumants = value;
				OnPropertyChanged("CheckoutArgumants");
			}
		}

		bool _acceptedByUser;

		public bool AcceptedByUser
		{
			get { return _acceptedByUser; }
			set
			{
				_acceptedByUser = value;
				OnPropertyChanged("AcceptedByUser");
			}
		}

		public void Checkout(string fullPath)
		{
			var fi = new FileInfo(fullPath);
			if(!fi.Exists)
			{
				throw new FileNotFoundException("", fullPath);
			}

			var psi = new ProcessStartInfo
			{
				FileName = Environment.ExpandEnvironmentVariables(CheckoutExecutable),
				Arguments = string.Format(CheckoutArgumants, fullPath),
				UseShellExecute = false,
				RedirectStandardError = true,
				RedirectStandardOutput = true,
				WindowStyle = ProcessWindowStyle.Minimized,
				WorkingDirectory = PathHelper.GetDirectoryName(fullPath),
				CreateNoWindow = true,
			};
			Process p;
			try
			{
				p = Process.Start(psi);
			}
			catch (Exception ex)
			{
				throw new Exception("Unable to start '" + psi.FileName + "': " + ex.Message);
			}
			var ok = p.WaitForExit(10000);
			if (!ok)
			{
				throw new Exception("Checkout timed out (> 10 sec)");
			}
			if (p.ExitCode != 0)
			{
				var outPut = p.StandardError.ReadToEnd() + p.StandardOutput.ReadToEnd();
				throw new Exception("Checkout failed: " + p.ExitCode + " " + outPut);
			}
			fi.Refresh();
			if(fi.IsReadOnly)
			{
				throw new Exception("Checkout succeed but file still readonly");
			}
		}

		#region Implementation of IDataErrorInfo

		public string this[string columnName]
		{
			get {
				try
				{
					switch (columnName)
					{
						case "CheckoutExecutable":
							var file = Environment.ExpandEnvironmentVariables(CheckoutExecutable);
							if (!PathHelper.FileExists(file))
							{
								return "File Not Found: " + file;
							}
							break;
					}
					return null;
				}
				catch (Exception ex)
				{
					return ex.Message;
				}
			}
		}

		public string Error
		{
			get
			{
				return null;
			}
		}

		#endregion
	}
}